import java.io.*;
import java.util.*;
public class Scanner {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public String textString;
	public String readFileToString(String filename) throws IOException
	{
		FileInputStream  inputStream = new FileInputStream(filename);
		StringBuffer buffer = new StringBuffer();
		String line;
		BufferedReader bufferReader = new BufferedReader(new InputStreamReader(inputStream));
		line = bufferReader.readLine();
		while(line != null)
		{
			buffer.append(line);
			line = bufferReader.readLine();			
		}
		inputStream.close();
		this.textString = buffer.toString();
		return this.textString;
	}
	public Token getNextToken()
	{
		Token nextToken = new Token();
		TokenType tokenType = new TokenType();
		if(this.textString == null)
		{
			nextToken.type = tokenType.FILEEOF;
			return nextToken;
		}
			
		StringTokenizer stringtokenizer = new StringTokenizer(this.textString);	
//		System.out.println("In the getNextToken: "+this.textString);
//		System.out.println("This.textString: "+ this.textString);
		if(stringtokenizer.hasMoreElements() == false)
		{
			nextToken.type = tokenType.FILEEOF;
			return nextToken;
		}
		String token= stringtokenizer.nextToken();	
		
//		System.out.println("This is the token " + token);
//		if(token.length() > 10)
//			return null;
		if((token.charAt(0)) == '(')
		{
			nextToken.type = tokenType.LPAREN;
//			System.out.println("LPAREN");
			int i = 0;
			while(true)
			{
				if(this.textString.charAt(i) != '(')
				{
					i++;
				}
				else
					break;
			}
			if(i != 0)
			{
				token = this.textString.substring(0,i);
				this.textString = this.textString.substring(i);
//				System.out.println("This.textString"+ this.textString); 
			}
			else
			{
				token = Character.toString(this.textString.charAt(0));
				this.textString = this.textString.substring(1);
//				System.out.println("This.textString"+ this.textString);
			}	
			this.textString = this.textString.substring(i);
//			System.out.println("This.TextString is " + this.textString);
			return nextToken;			
		}
		else if((token.charAt(0)) == ')')
		{
			nextToken.type = tokenType.RPAREN;
//			System.out.println("RPAREN");
			this.textString = this.textString.substring(1);	
			return nextToken;			
		}
		else if ((token.charAt(0)) == '.')
		{
			nextToken.type = tokenType.DOT;
//			System.out.println("DOT");
//			System.out.println("this textString" + this.textString.indexOf(token.charAt(0)));
			this.textString = this.textString.substring(this.textString.indexOf(token.charAt(0))+1);	
//			System.out.println("After delete dot the string is " + this.textString);
			return nextToken;	
		}

		if(this.judgeIDorInteger(token) == 1)
		{
			nextToken.type = TokenType.INT;
			nextToken.Value = token;
			//System.out.println("Token is integer: " + token);
			if(this.textString.length() > token.length())
			{
				this.textString = this.textString.substring(token.length()+1);
			}
			else
			{
				this.textString = null;
			}
				
			//System.out.println("This.textString: "+ this.textString);
			return nextToken;
		}
		else if(this.judgeIDorInteger(token) == 2)
		{
			nextToken.type = TokenType.ID;
			nextToken.Value = token;
//			System.out.println("Token is IDENTIFIER: " + token);
			//this.textString = this.textString.substring(token.length()+1);
			if(this.textString.length() > token.length())
			{
				this.textString = this.textString.substring(token.length()+1);
			}
			else
			{
				this.textString = null;
			}
//			System.out.println("This.textString: "+ this.textString);
			return nextToken;
		}
		else if(this.judgeIDorInteger(token) == 3)
		{
			int i = 0;
			while(true)
			{
				if(this.textString.charAt(i) != '(')
				{
					i++;
				}
				else
					break;
			}
//			token = this.textString.substring(0,i-1);
			//token = this.textString.substring(this.textString.indexOf(token),i);
			if(i != 0)
			{
				//token = this.textString.substring(0,i);
				token = this.textString.substring(this.textString.indexOf(token.charAt(0)),i);
				this.textString = this.textString.substring(i);
				//System.out.println("This.textString"+ this.textString); 
			}
			else
			{
				token = Character.toString(this.textString.charAt(0));
				this.textString = this.textString.substring(1);
				//System.out.println("This.textString"+ this.textString);
			}
			nextToken.Value = token;
			this.textString = this.textString.substring(i);
//			System.out.println("This.textString: "+ this.textString);
			return nextToken;
		}
		else if(this.judgeIDorInteger(token) == 4)
		{
			int i = 0;
			while(true)
			{	
				if(this.textString.charAt(i) != ')')
				{
					i++;
				}                    
				else
					break;
			}
			if(i != 0)
			{
				token = this.textString.substring(this.textString.indexOf(token.charAt(0)),i);
				//token = this.textString.substring(0,i);
				this.textString = this.textString.substring(i);
//				System.out.println("This.textString"+ this.textString); 
			}
			else
			{
				token = Character.toString(this.textString.charAt(0));
				this.textString = this.textString.substring(1);
//				System.out.println("This.textString"+ this.textString);
			}
//			System.out.println("Token 1 is "+ token.charAt(1));
			nextToken.Value = token;
			if(this.judgeIDorInteger(token) == 1)
			{
				nextToken.type = TokenType.INT;
			}
			else if(this.judgeIDorInteger(token) == 2)
			{
				nextToken.type = TokenType.ID;
			}
			else
			{
				return null;
			}
			
//			System.out.println("This.textString.subString: " + token);
//			token = this.textString.substring(this.textString.indexOf(token),i);
//			System.out.println("This.textString: "+ this.textString);
			return nextToken;
		}
		else if(this.judgeIDorInteger(token) == 5)
		{
			int i = 0;
			while(true)
			{
				if(this.textString.charAt(i) != '.')
				{
					i++;
				}
				else
					break;
			}
//			token = this.textString.substring(0,i-1);
			//token = this.textString.substring(this.textString.indexOf(token),i);
			if(i != 0)
			{
				token = this.textString.substring(0,i);
				this.textString = this.textString.substring(i);
				//System.out.println("This.textString"+ this.textString); 
			}
			else
			{
				token = Character.toString(this.textString.charAt(0));
				this.textString = this.textString.substring(1);
				//System.out.println("This.textString"+ this.textString);
			}
			nextToken.Value = token;
			if(this.judgeIDorInteger(token) == 1)
			{
				nextToken.type = TokenType.INT;
			}
			else if(this.judgeIDorInteger(token) == 2)
			{
				nextToken.type = TokenType.ID;
			}
			else
			{
				return null;
			}
			//nextToken.type = TokenType.DOT;
			//this.textString = this.textString.substring(i);
//			System.out.println("This.textString: "+ this.textString);
			return nextToken;
		}		
		else if((this.judgeIDorInteger(token) <0))
		{
			return null;//Error for ID and Integer
		}
		return null;		
	}
	
	
	
	public int judgeIDorInteger(String s)
	{
		int i = 0;
		int count = 0;
		if((s.charAt(0) >= '0') && (s.charAt(0) <= '9'))
		{
			count = 1;			
			for(i = 1; i < s.length(); i++)
			{
				if((s.charAt(i) >= '0') && (s.charAt(i) <= '9'))
					count ++;	
				else if(s.charAt(i) == '(')
					return 3;
				else if(s.charAt(i) == ')')
					return 4;
				else if(s.charAt(i) == '.')
					return 5;
			}
			if(count == s.length())
			{
				return 1;//It is an integer
			}
			else
			{
				return -1;//The first letter is integer, and it contain the other char, it is an error;
			}			
		}
		if((s.charAt(0) >= 'A') && (s.charAt(0) <= 'Z'))
		{
			count  = 1;
			for(i = 1; i < s.length(); i++)
			{
				if(((s.charAt(i) >= 'A')&&(s.charAt(i) <= 'Z')))
				{
					count++;
				}
				else if((s.charAt(i) >= '0') && (s.charAt(i)) <= '9')
				{
					count++;
				}
				else if(s.charAt(i) == '(')
					return 3;
				else if(s.charAt(i) == ')')
					return 4;
				else if(s.charAt(i) == '.')
					return 5;
			}
			if(count == s.length())
			{
				return 2;//It is an Identifier
			}
			else
			{
				return -2;//The first letter is an Uppercase alphabet, however the following can't be the alphabet
			}
		}
		else		
		return -3;//defalut error
	}
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		String filename = new String("/home/lixinyu/workspace/Lisp/src/test.txt");
		Scanner scanner =new Scanner();
		scanner.readFileToString(filename);
		Token token;
		scanner.readFileToString(filename);
		while(true)
		{
			try
			{
				 token = scanner.getNextToken();

			}catch(Exception e)
			{
				token = null;
			}
			if(token.type != TokenType.FILEEOF)
			{
				switch(token.type)
				{
					case TokenType.DOT:
					{
						//System.out.println("Dot");
						System.out.print(". ");
						break;
					}
					case TokenType.INT:
					{
						//System.out.println("Integer " + token.Value);
						System.out.print(token.Value);
						break;
					}
					case TokenType.ID:
					{
						//System.out.println("ID " + token.Value);
						System.out.print(token.Value);
						break;
					}
					case TokenType.LPAREN:
					{
						//System.out.println("LPAREN");
						System.out.print("(");
						break;
					}
					case TokenType.RPAREN:
					{
						//System.out.println("RPAREN");
						System.out.print(")");
						break;
					}				
				}
			}
			else
				break;
		}
	}

}